package com.ywk.base.concurrency.thread.createWay;

import com.google.common.collect.Lists;
import lombok.SneakyThrows;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * 参考：https://blog.csdn.net/2401_85648342/article/details/139976604
 * @Author zbh
 * @Date 2025/3/28
 */
public class CompletableFutureTest {
    public static void main(String[] args) {
        way4();
    }

    /**
     * 使用ForkJoinPool.commonPool()作为它的线程池执行异步代码,
     */
    private static void way1(){
        System.out.println("当前调用者线程为:" + Thread.currentThread().getName());
        CompletableFuture.runAsync(()->
            System.out.println("异步方法内当前执行线程为:" + Thread.currentThread().getName())
        );
        System.out.println("main-end");
    }

    /**
     * 使用指定的线程池执行异步代码。此异步方法无法返回值
     */
    private static void way2(){
        System.out.println("当前调用者线程为:" + Thread.currentThread().getName());
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 3; i++) {
            CompletableFuture.runAsync(()->{
                System.out.println("异步方法内当前执行线程为:" + Thread.currentThread().getName());
            },threadPool);
        }
        threadPool.shutdown();
        System.out.println("main-end");
    }

    /**
     * 使用指定的线程池执行异步代码。此异步方法有返回值
     */
    @SneakyThrows
    private static void way3(){
        System.out.println("当前调用者线程为:" + Thread.currentThread().getName());
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        List<CompletableFuture<String>> rs=new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            int finalI = i;
            CompletableFuture<String> result = CompletableFuture.supplyAsync(() -> {
                System.out.println("异步方法内当前执行线程为:" + Thread.currentThread().getName());
                return "hello,word"+ finalI;
            }, threadPool);
            rs.add(result);
        }
        threadPool.shutdown();
        System.out.println(rs.get(0).get());
        System.out.println(rs.get(1).get());
        System.out.println(rs.get(2).get());
        System.out.println("main-end");
    }

    /**
     * 结合way3，使用分片方式
     */
    @SneakyThrows
    private static void way4(){
        System.out.println("当前调用者线程为:" + Thread.currentThread().getName());
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        //模拟需要处理的数据
        ArrayList<Integer> data = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            data.add(i);
        }
        //分片数据
        List<List<Integer>> partition = Lists.partition(data, 20);
        //分片处理逻辑
        CompletableFuture<String>[] futures = new CompletableFuture[partition.size()];
        for (int i = 0; i < futures.length; i++) {
            int finalI = i;
            List<Integer> list = partition.get(i);
            futures[i] = CompletableFuture.supplyAsync(() -> {
                System.out.println("异步方法内当前执行线程为:" + Thread.currentThread().getName());
                System.out.println(list);
                return "success"+finalI;
            },threadPool);
        }
        //阻塞主线程，等待所有分片任务都执行完毕
        CompletableFuture.allOf(futures).join();
        threadPool.shutdown();
        System.out.println(futures[0].get());
        System.out.println(futures[1].get());
        System.out.println(futures[2].get());
        System.out.println(futures[3].get());
        System.out.println(futures[4].get());
        System.out.println("main-end");
    }
}
